package initialization;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.LinkedHashMap;
import operations.Operation;
import util.DebugConfig;
import util.GAConfig;
import util.Log;
import ga.GAInfo;
import ga.Individual;
import mdr.MethodRelations;
import model.TestClusterBuilder;
import model.StatementKind;
public class MethodDependencePopulationInitializer implements PopulationInitializer{ 
	protected GAInfo gaInfo;
	private static final int POPULATION_SIZE    = GAConfig.PopulationSize;
	private static final int TEST_SIZE_GOAL = GAConfig.TestCaseSize;
	@Override
	public Individual[] createPopulation() {
		TestClusterBuilder TestCluster=gaInfo.getTestCluster();
		Map<Class<?>,  List<StatementKind>> constructorRelative =this.getRecommendStatements();

		Individual[] population = new Individual[POPULATION_SIZE];
		//Generate random population
		for(int individual = 0; individual < POPULATION_SIZE; individual++) {
			// Create initial Objects available for testing
			 List<Operation> initialConstructors= Operation.dependenceGenerateInitialConstructors(TestCluster);

			List<Operation> ops = new LinkedList<Operation>();
			 ops.addAll(Operation.randomlyGenerateOperation(TestCluster,TEST_SIZE_GOAL));
			population[individual] = new Individual(initialConstructors,ops);
		}		
		return population;
	}
	@Override
	public void printPopulation(){
		if(!DebugConfig.PopulationInitializer)
			return;
			Log.log("++++++++++++++++++++++++++++++++++++++++");
			Log.log("\t\t Generation "+ gaInfo.getGeneration());
			for(Individual individual : this.gaInfo.getPopulation()) {
				Log.log("------------------------------------------");
				Log.log( individual.toString()+ " fitness: "+ individual.getFitness() + " size:"+ individual.getSize());
			}
	}
	
	@Override
	public void setExtraInfo(GAInfo gaInfo) {
		this.gaInfo = gaInfo;
	}
	private  Map<Class<?>,  List<StatementKind>>  getRecommendStatements(){ 
		MethodRelations relations =gaInfo.getMethodRelations().getRelations();
		Map<Class<?>, List<StatementKind>> constructorsRelative =relations.getConstructorDependences();
		return constructorsRelative;
	}
}
